package com.example.stock.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import com.example.stock.entity.dao.RuleDao;
import com.example.stock.entity.dao.UnitDao;
import com.example.stock.entity.eo.RuleEo;
import com.example.stock.entity.eo.UnitEo;
import com.example.stock.service.IRuleService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RuleServiceImpl implements IRuleService {

    @Resource
    private RuleDao ruleDao;
    @Resource
    private UnitDao unitDao;

    @Override
    public List<RuleEo> list() {
        Map<Integer, List<UnitEo>> ruleIdMapUnits = unitDao.list().stream().collect(Collectors.groupingBy(UnitEo::getRuId));
        List<RuleEo> list = ruleDao.list();
        for (RuleEo ruleEo : list) {

            //计算策略涨跌
            List<RuleEo.UpDnCalc> upDnCalcList = listUpDnCalc(ruleEo);
            ruleEo.setUpDnCalcList(upDnCalcList);

            //设置股票名称
            List<UnitEo> unitList = ruleIdMapUnits.get(ruleEo.getId());
            if (CollectionUtil.isNotEmpty(unitList)) {
                //根据TrGroup去重
                ArrayList<UnitEo> unitEos = unitList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(UnitEo::getTrGroup))), ArrayList::new));
                String unitNames = unitEos.stream().map(unitEo -> unitEo.getStName()).collect(Collectors.joining(", "));
                ruleEo.setUnitNames(unitNames);
            }
        }
        return list;
    }

    public List<RuleEo.UpDnCalc> listUpDnCalc(RuleEo ruleEo) {
        List<RuleEo.UpDnCalc> upDnCalcList = new ArrayList<>();
        for (int i = ruleEo.getTopStep() - 1; i > ruleEo.getTopStep() - 13; i--) {
            RuleEo.UpDnCalc upDnCalc = getUpDnCalc(ruleEo, i);
            upDnCalcList.add(upDnCalc);
        }
        return upDnCalcList;
    }

    public RuleEo.UpDnCalc getUpDnCalc(RuleEo ruleEo, int i) {
        RuleEo.UpDnCalc upDnCalc = new RuleEo.UpDnCalc();
        upDnCalc.setTrStep(i);

        if (i >= ruleEo.getUpPoint()) {
            double v = (i - ruleEo.getUpPoint()) * ruleEo.getUpAdd() + ruleEo.getUpInit();
            upDnCalc.setUpPercent(NumberUtil.round(v, 6).doubleValue());
        }

        if (i <= ruleEo.getDnPoint()) {
            double v1 = (ruleEo.getDnPoint() - i) * ruleEo.getDnAdd() + ruleEo.getDnInit();
            upDnCalc.setDnPercent(NumberUtil.round(v1, 6).doubleValue());
        }
        return upDnCalc;
    }

    @Override
    public void save(RuleEo ruleEo) {
        if (ruleEo.getId() != null) {
            validateRule(ruleEo.getId());
        }
        ruleDao.saveOrUpdate(ruleEo);
    }

    @Override
    public void deleteById(Integer id) {
        validateRule(id);
        ruleDao.removeById(id);

    }

    private void validateRule(Integer id) {
        List<UnitEo> unitEos = unitDao.listByRuleId(id);
        if (CollectionUtil.isNotEmpty(unitEos)) {
            throw new RuntimeException("rule在使用");
        }
    }

    @Override
    public RuleEo getById(Integer id) {
        return ruleDao.getById(id);
    }
}
